﻿using System;
using System.Drawing;

namespace Swsk33.GISEndExercise.Model
{
	/// <summary>
	/// 二维线段
	/// </summary>
	public class Line
	{
		private PointF start;

		private PointF end;

		/// <summary>
		/// 线段起始点
		/// </summary>
		public PointF Start { get => start; set => start = value; }

		/// <summary>
		/// 线段终止点
		/// </summary>
		public PointF End { get => end; set => end = value; }

		/// <summary>
		/// 用两个点初始化线段（构造器依赖注入）
		/// </summary>
		/// <param name="start">起始点</param>
		/// <param name="end">终止点</param>
		public Line(PointF start, PointF end)
		{
			Start = start;
			End = end;
		}

		/// <summary>
		/// 判断传入两个点是否在自身同侧
		/// </summary>
		/// <param name="point1">传入第一个点</param>
		/// <param name="point2">传入第二个点</param>
		/// <returns>传入的两个点是否在自身同侧，如果某个点在线段上就判定为不在同侧</returns>
		public bool IsSameSide(PointF point1, PointF point2)
		{
			Vector startToPoint1 = new Vector(Start, point1);
			Vector startToPoint2 = new Vector(Start, point2);
			Vector self = new Vector(this);
			// 两者相乘为异号说明不在同侧
			if (self.CrossProduct(startToPoint1) * self.CrossProduct(startToPoint2) <= 0)
			{
				return false;
			}
			return true;
		}

		/// <summary>
		/// 判断自身是否和传入线段相交
		/// </summary>
		/// <param name="line">传入线段</param>
		/// <returns>自身和传入的线段是否相交，即使一个线段的端点在另一个线段上也算相交</returns>
		public bool IsIntersect(Line line)
		{
			if (!IsSameSide(line.Start, line.End) && !line.IsSameSide(Start, End))
			{
				return true;
			}
			return false;
		}

		/// <summary>
		/// 获取点到线段的垂距，包括延长线
		/// </summary>
		/// <param name="point">传入点</param>
		/// <returns>传入点到线段自身垂距</returns>
		public double GetPointToLineOffset(PointF point)
		{
			Vector startToPoint = new Vector(Start, point);
			Vector selfUnit = new Vector(this).GetUnitVector();
			return Math.Abs(startToPoint.CrossProduct(selfUnit));
		}
	}
}